JS 异步编程及常考面试题
1. 回调函数
面试题:回调函数有什么缺点?如何解决回调地狱问题?
回调容易写出回调地狱,根本问题是嵌套函数存在耦合性,一旦有所改动就会牵一发而动全身,并且嵌套函数多了会很难处理错误。回调函数不能使用 try catch 捕获错误,不能直接 return。
如何解决回调地狱的问题?:用 Generator/Promise/async&&await 来改善。
2. Generator
面试题:你理解的 Generator 是什么??
Generator 是生成器,一种返回迭代器(是一种特殊对象,具有一些专门为迭代过程设计的专有接口,所有的迭代器对象都有 next()方法,每次调用都会返回结果对象{value:’xxx’,done:true/false})的函数,用处是可以控制函数的执行,通过 function 关键字后的*来表示,函数中会使用 yield 关键字。
1 | function *foo(x) { |
使用 Generator 来解决回调地狱的问题:
1 | function *fetch() { |
3.Promise
面试题:Promise 的特点是什么,分别有什么优缺点?什么是 Promise 链?Promise 构造函数执行和 then 函数执行有什么区别?
- 特点和优缺点:
- Promise 有三种状态:等待中(pending)、完成了(resolved)、拒绝了(rejected),一旦从等待状态变成了其他状态就不能更改状态了
1 | new Promise((resolve, reject) => { |
- 在构造 Promise 的时候,构造函数内部的代码是立即执行的
1 | new Promise((resolve, reject) => { |
缺点:无法取消 Promise,错误需要通过回调函数捕获。
Promise 实现了链式调用,每次调用 then 之后返回一个全新的Promise(因为状态不可变),如果在 then 中使用了 return,那么 return 的值会被 Promise.resolve()包装。
使用 Promise 来解决回调地狱的问题:
1 | ajax(url) |
4.async 及 await
面试题:async 及 await 的特点,它们的优点和缺点分别是什么?await 原理是什么?
- await 就是 generator 加上 Promise 的语法糖,且内部实现了自动执行 generator。一个函数如果加上 async,那么函数就会返回一个 Promise,async 就是将函数返回值用 RESOLVE 包裹了,和 then 中处理返回值一样,并且 await 只能配套 async 使用
- 相比于直接使用 Promise,处理掉了 then 的调用链,优雅的解决了回调地狱的问题
1 | async function test() { |
缺点:await 将异步代码改造成了同步代码,如果多个异步没有依赖性,使用了 await 会导致性能上的降低。(一个执行完成才会执行下一个)
await 创建 promise,所以 await 之后的代码才是异步的。